package spring_06_AspectJ.example;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component("myAspect")
@Aspect
public class MyAspect {
	/**
     * JoinPoint 能获取目标方法的一些基本信息
     * @param joinPoint
     */
	@Before("execution(* spring_05_aop.example.StaticAgent.Interface.*.*(..))")
	public void myBefore(JoinPoint joinPoint){
		System.out.println("前置通知 ： "+joinPoint.getSignature().getName());
	}
	
	@AfterReturning(value="execution(* spring_05_aop.example.StaticAgent.Interface.*.*(..))",returning="ret")
	public void myAfterReturning(JoinPoint joinPoint,Object ret){
		System.out.println("后置通知 ："+joinPoint.getSignature().getName()+ " , -->" + ret);
	}
	
	@After("execution(* spring_05_aop.example.StaticAgent.Interface.*.*(..))")
	public void myAfter(){
		System.out.println("最终通知");
	}
	
	@AfterThrowing(value="execution(* spring_05_aop.example.StaticAgent.Interface.*.*(..))",throwing="e")
	public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
		System.out.println("抛出异常通知 ： " +e.getMessage());
	}
	
	@Around("execution(* spring_05_aop.example.StaticAgent.Interface.*.*(..))")
	public Object myAround(ProceedingJoinPoint joinPoint)throws Throwable{
		System.out.println("前置通知");
		//手动执行目标方法
		Object object = joinPoint.proceed();
		System.out.println("后置通知");
		return object;
	}
	
	/*
	 * 这里有个问题，环绕方式包括了前后，所以当时环绕和前置同时存在的时候，会怎么执行？
	 * 然后这个和xml里面配置的先后顺序有关系吗？
	 * 答：有。同心圆原理
	 * 
	 * 
	 */
}
